package com.seatatcc.stock.service;

import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import io.seata.rm.tcc.api.LocalTCC;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;

/****************************************************
 *
 * 定义TCC 的接口，注解 @LocalTCC 表示该接口是一个TCC 接口
 * todo 注意：@LocalTCC 一定要标注在接口上
 *
 * 注解 @LocalTCC 适用于SpringCloud+Feign模式下的TCC
 * 注解 @TwoPhaseBusinessAction 注解try方法，其中name为当前tcc方法的bean名称，写方法名便可（全局唯一），
 * commitMethod指向提交方法，rollbackMethod指向事务回滚方法。指定好三个方法之后，seata会根据全局事务的成功或失败，
 * 去帮我们自动调用提交方法或者回滚方法。
 * 注解 @BusinessActionContextParameter 注解可以将参数传递到二阶段（commitMethod/rollbackMethod）的方法。
 * BusinessActionContext 便是指TCC事务上下文
 *
 * @author lbf
 * @date 2025/7/16 17:15
 ****************************************************/
@LocalTCC
public interface StockService {

    /**
     * 定义两阶段提交
     * name = 该tcc的bean名称，一般是try方法名称,全局唯一
     * commitMethod = commit 为二阶段确认方法
     * rollbackMethod = rollback 为二阶段取消方法
     *
     * 若TCC接口中的方法带有参数，则需要 BusinessActionContextParameter注解 将参数传递到二阶段中，如：
     *
     *     @TwoPhaseBusinessAction(name = "decrement",commitMethod = "commitTcc",rollbackMethod = "cancel")
     *     void decrement(@BusinessActionContextParameter(paramName = "money") int money);
     *
     *
     */
    @TwoPhaseBusinessAction(name = "decrement",commitMethod = "commitTcc",rollbackMethod = "cancel")
    void decrement();

    /**
     * 确认方法、可以另命名，但要保证与commitMethod一致
     * context可以传递try方法的参数
     *
     * @param context 上下文
     * @return boolean
     */
    boolean commitTcc(BusinessActionContext context);

    /**
     * 二阶段回滚方法，名称与 rollbackMethod 一致
     *
     * @param context 上下文
     * @return boolean
     */
    boolean cancel(BusinessActionContext context);
}
